package work.jame.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import work.jame.blog.framework.exception.db.DataNotExistException;
import work.jame.blog.framework.exception.db.InsertDataBaseException;
import work.jame.blog.framework.result.PageResult;
import work.jame.blog.framework.utils.SqlUtils;
import work.jame.blog.framework.utils.security.SpringSecurityUtils;
import work.jame.blog.pojo.Article;
import work.jame.blog.mapper.ArticleMapper;
import work.jame.blog.pojo.ArticleTag;
import work.jame.blog.pojo.ArticleTagRelation;
import work.jame.blog.pojo.dto.ArticleDTO;
import work.jame.blog.pojo.vo.ArticleDetailVO;
import work.jame.blog.pojo.vo.ArticleSynopsisVO;
import work.jame.blog.pojo.vo.ArticleVO;
import work.jame.blog.pojo.vo.PublishUserVO;
import work.jame.blog.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Jame
 * @since 2023-05-17
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {


    @Resource
    private ArticleMapper articleMapper;

    @Autowired
    private ArticleTagService articleTagService;

    @Autowired
    private ArticleTagRelationService articleTagRelationService;

    @Autowired
    private UserArticleHistoryService userArticleHistoryService;

    @Autowired
    private UserService userService;


    @Override
    @Transactional
    public Long publish(ArticleDTO articleDTO) {
        List<ArticleTag> articleTags = articleDTO.getArticleTags();
        articleTagService.saveOrQueryArchiveTag(articleTags);
        Article article = articleDTO.getArticle();
        //如果用户没有写摘要,则截取正文前100字
        if (!StringUtils.hasText(article.getArticleAbstract())) {
            String content = article.getContent();
            String articleAbstract = content.length() > 100 ? content.substring(0, 100) : content;
            article.setArticleAbstract(articleAbstract);
        }
        Long userId = SpringSecurityUtils.getCurrentLoginUserId();
        article.setUserId(userId);
        if (!this.save(article)) {
            throw new InsertDataBaseException("添加文章失败");
        }
        for (ArticleTag tag : articleTags) {
            ArticleTagRelation tagRelation = new ArticleTagRelation();
            tagRelation.setArticleId(article.getId());
            tagRelation.setArticleTagId(tag.getId());
            if (!articleTagRelationService.save(tagRelation)) {
                throw new InsertDataBaseException("添加文章标签关系");
            }
        }
        return article.getId();
    }

    @Override
    public ArticleDetailVO getArticleDetail(Long articleId) {
        QueryWrapper<Article> wrapper = new QueryWrapper<>();
        wrapper.eq("id", articleId);
        wrapper.select("user_id");
        Article article = this.getOne(wrapper);
        if (Objects.isNull(article)) {
            throw new DataNotExistException("未找到对应的文章");
        }
        Long userId = SpringSecurityUtils.getCurrentLoginUserId();

        //添加用户历史记录
        //忽略结果
        userArticleHistoryService.saveOrUpdateUserArticleHistory(userId, articleId);

        //获取文章相关信息
        ArticleVO articleVO = articleMapper.queryArticleInfo(articleId, userId);
        if (Objects.isNull(articleVO)) {
            throw new DataNotExistException("未找到对应的文章");
        }
        List<ArticleTag> articleTags = articleTagRelationService.queryArticleTagsByArticleId(articleId);
        articleVO.setTags(articleTags);
        //获取发布者用户相关信息
        PublishUserVO publishUserVO = userService.queryPublishUserInfo(article.getUserId());
        ArticleDetailVO articleDetailVO = new ArticleDetailVO();
        articleDetailVO.setArticleVO(articleVO);
        articleDetailVO.setPublishUserVO(publishUserVO);
        return articleDetailVO;
    }

    @Override
    public boolean queryArticlePublishIsThisUser(Long articleId, Long userId) {
        QueryWrapper<Article> wrapper = new QueryWrapper<>();
        wrapper.eq("id", articleId)
                .eq("user_id", userId);
        return this.count(wrapper) == 1;
    }

    @Override
    public Long queryPublisherIdByArticleId(Long articleId) {
        return articleMapper.queryPublisherIdByArticleId(articleId);
    }

    @Override
    public PageResult<ArticleSynopsisVO> queryHomeArticleSynopsis(String articleTitle, Long pageNumber, Long pageSize, int orderRule) {
        Long synopsisCount = articleMapper.queryHomeArticleSynopsisCount(articleTitle);
        if (synopsisCount == 0) {
            return PageResult.noData();
        }
        long startLine = SqlUtils.startLine(pageNumber, pageSize);
        List<ArticleSynopsisVO> synopsis = articleMapper.queryHomeArticleSynopsis(articleTitle, startLine, pageSize, orderRule);
        return PageResult.succeed(synopsis, pageNumber, pageSize, synopsisCount);
    }

    @Override
    public PageResult<ArticleSynopsisVO> queryHomeArticleSynopsis(Long pageNumber, Long pageSize, int orderRule) {
        return this.queryHomeArticleSynopsis(null, pageNumber, pageSize, orderRule);
    }
}
